<?php 

/**
 * 数据库操作类
 */

class Model
{
    protected $link = null;//连接标识
    protected $tabName = null;//用于存储表名
    protected $fields = [];//字段列表
    protected $pk;//主键字段的名字
    protected $keys;//要查询的字段
    protected $where;//查询条件
    protected $order;//排序条件
    protected $limit;//分页条件

    /**
     * 初始化数据库连接
     */
    public function __construct($tabName)
    {
        $this->link = mysqli_connect(HOST,USER,PASS,DB);
        mysqli_set_charset($this->link, CHAR);
        $this->tabName = $tabName;//接收实例化时传入的表名
        $this->getField();//自动获取 该表的所有字段们
    }

    //查询所有数据
    public function select()
    {
        $keys = '*';//默认查询全部
        if (!empty($this->keys)) {
            $keys = $this->keys;
            $this->keys = null;//每次清除之前的查询条件
        }
        $where = '';//默认无查询
        if (!empty($this->where)) {
            $where = 'WHERE '.$this->where;
            $this->where = null;//每次清除之前的查询条件
        }
        $order = '';//默认无排序
        if (!empty($this->order)) {
            $order = 'ORDER BY '.$this->order;
            $this->order = null;//每次清除之前的查询条件
        }
        $limit = '';//默认无分页
        if (!empty($this->limit)) {
            $limit = 'LIMIT '.$this->limit;
            $this->limit = null;//每次清除之前的查询条件
        }
        $sql = "SELECT {$keys} FROM {$this->tabName} {$where} {$order} {$limit}";
        return $this->query($sql);
    }

    //查询单条数据
    public function find($findValue, $findKey = 'id')
    {
        $keys = '*';//默认查询全部
        if (!empty($this->keys)) {
            $keys = $this->keys;
            $this->keys = null;//每次清除之前的查询条件
        }
        $sql = "SELECT {$keys} FROM {$this->tabName} WHERE {$findKey}='{$findValue}' LIMIT 1";
        //接收查询结果
        $data = $this->query($sql);
        //判断结果是否为false
        if (empty($data)) {
            return false;
        }
        return $data[0];//返回一维数组
    }

    //获取要查询的字段,对象链操作
    public function field($arr)
    {
        //判断参数是否为数组
        if (!is_array($arr)) {return $this;}
        // 遍历所有参数,排除非法字段
        foreach ($arr as $key => $val) {
            if (!in_array($val, $this->fields)) {
                unset($arr[$key]);
            }
        }
        //判断筛选完的数组是否为空
        if (empty($arr)) {return $this;}
        //存储要查询的字段
        $this->keys = implode(',', $arr);

        //返回自己
        return $this;
    }

    public function where($where)
    {
        //设置要查询的条件
        $this->where = $where;
        //返回自己
        return $this;
    }

    //排序
    public function order($order)
    {
        $this->order = $order;//设置要排序的条件
        return $this;//返回自己
    }
    //分页
    public function limit($limit)
    {
        $this->limit = $limit;//设置要排序的条件
        return $this;//返回自己
    }

    //删除数据
    public function delete($delValue, $delKey = 'id')
    {
        $sql = "DELETE FROM {$this->tabName} WHERE {$delKey}='{$delValue}'";
        return $this->execute($sql);
    }

    //新增数据
    public function insert($data = [])
    {
        // 直接给参数赋值POST不科学
        // 判断 如果data为空数组 则赋值为POST数据
        if (empty($data)) {
            $data = $_POST;
        }
        //筛选数据
        foreach ($data as $k => $v) {
            //如果POST里的$k 在字段列表之中 就把他保留下来
            if (in_array($k, $this->fields)) {
                $list[$k] = $v;
            }
        }

        //生成SQL中的条件 key与value
        $keys = implode(',', array_keys($list));
        $values = implode("','", array_values($list));

        //预写SQL
        $sql = "INSERT INTO {$this->tabName} ({$keys}) VALUES('{$values}')";
        //执行操作
        return $this->execute($sql);
    }

    //更新数据
    public function update($data = [])
    {
        // 直接给参数赋值POST不科学
        // 判断 如果data为空数组 则赋值为POST数据
        if (empty($data)) {
            $data = $_POST;
        }
        //筛选数据
        foreach ($data as $k => $v) {
            if (in_array($k, $this->fields) && $k != $this->pk) {
                $list[] = "`{$k}`='{$v}'";
            }
        }
        //生成SET条件
        $set = implode(',', $list);

        //SQL
        $sql = "UPDATE {$this->tabName} SET {$set} WHERE `{$this->pk}`='{$data[$this->pk]}'";
        //执行更新
        return $this->execute($sql);
    }


    //统计条目数量
    public function count()
    {
        $where = '';//默认无查询
        if (!empty($this->where)) {
            $where = 'WHERE '.$this->where;
            $this->where = null;//每次清除之前的查询条件
        }
        $sql = "SELECT COUNT(*) total FROM {$this->tabName} {$where}";
        $total = $this->query($sql);
        return $total[0]['total'];
    }

    /**
     * 销毁资源
     */
    public function __destruct()
    {
        mysqli_close($this->link);
    }

    /*****************************************************/
    //获取表内所有字段
    private function getField()
    {
        //查询表结构
        $sql = "DESC {$this->tabName}";
        $list = $this->query($sql);
        // var_dump($list);
        //遍历得到全部的字段名字
        $fields = [];
        foreach ($list as $val) {
            $fields[] = $val['Field'];
            //获取主键
            if ($val['Key'] == 'PRI') {
                $this->pk = $val['Field'];
            }
        }
        // 赋值给属性
        $this->fields = $fields;
    }

    /**
     * 执行查询
     * @param  string $sql SQL语句
     * @return array/bool  返回查询结果,二维数组 或 返回false
     */
    private function query($sql)
    {
        //执行SQL语句
        $result = mysqli_query($this->link, $sql);
        //判断结果
        if ($result && mysqli_num_rows($result) > 0) {
            $list = [];
            $list = mysqli_fetch_all($result, MYSQLI_ASSOC);
            mysqli_free_result($result);
            return $list;//返回查询结果,二维数组
        } else {
            return false; // 查询失败返回false
        }
    }

    //执行增删改操作
    private function execute($sql)
    {
        //执行SQL语句
        $result = mysqli_query($this->link, $sql);
        // 处理结果集
        if ($result && mysqli_affected_rows($this->link) > 0) {
            //添加时会返回自增ID
            if (mysqli_insert_id($this->link) > 0) {
                //增加执行成功
                return mysqli_insert_id($this->link);
            } else {
                //删改执行成功
                return true;
            }
        } else {
            //操作失败
            return false;
        }
    }


}



